<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */
declare (strict_types=1);

namespace app\madmin\service;

use app\index\util\CreateNo;
use app\madmin\model\Configuration;
use app\madmin\model\PayMode;
use think\Exception;
use WeChat\Pay;

class PaymentService
{

    private $options;
    private $trade;

    public function __construct()
    {
        $this->trade = CreateNo::buildTransfersNo();
    }

    /**
     * 余额提现通过
     * @param string $baseIn
     * @param string $method
     * @param string $openid
     * @param float $amount
     * @return array
     * @throws Exception
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function totalTransfers(string $baseIn, string $method, string $openid, float $amount)
    {

        $this->getOptions($baseIn, $method);
        $jsapiOptions = $this->getJsapiOptions();
        $data = [
            "partner_trade_no" => $this->trade,
            'openid' => $openid,
            "check_name" => "NO_CHECK",
            "amount" => bcmul((string)$amount, (string)100, 0),
            "desc" => "余额提现通过",
        ];

        $transfers = new Pay($jsapiOptions);
        return $transfers->createTransfers($data);
    }

    /**
     * 商户提现申请通过
     * @param string $baseIn
     * @param string $method
     * @param string $openid
     * @param float $amount
     * @return array
     * @throws Exception
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function merchantTransfers(string $baseIn, string $method, string $openid, float $amount)
    {

        $this->getOptions($baseIn, $method);
        $jsapiOptions = $this->getJsapiOptions();

        $data = [
            "partner_trade_no" => $this->trade,
            'openid' => $openid,
            "check_name" => "NO_CHECK",
            "amount" => bcmul((string)$amount, (string)100, 0),
            "desc" => "商户提现通过",
        ];

        $transfers = new Pay($jsapiOptions);
        return $transfers->createTransfers($data);
    }

    /**
     * 推广员提现通过
     * @param string $baseIn
     * @param string $method
     * @param string $openid
     * @param float $amount
     * @return array
     * @throws Exception
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function agentTransfers(string $baseIn, string $method, string $openid, float $amount)
    {
        $this->getOptions($baseIn, $method);
        $jsapiOptions = $this->getJsapiOptions();

        $data = [
            "partner_trade_no" => $this->trade,
            'openid' => $openid,
            "check_name" => "NO_CHECK",
            "amount" => bcmul((string)$amount, (string)100, 0),
            "desc" => "分销提现通过",
        ];

        $transfers = new Pay($jsapiOptions);
        return $transfers->createTransfers($data);
    }

    /**
     * 推广员提现通过
     * @param string $baseIn
     * @param string $method
     * @param string $openid
     * @param float $amount
     * @return array
     * @throws Exception
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function CommissionAssessmentTransfers(string $baseIn, string $method, string $openid, float $amount)
    {
        $this->getOptions($baseIn, $method);
        $jsapiOptions = $this->getJsapiOptions();

        $data = [
            "partner_trade_no" => $this->trade,
            'openid' => $openid,
            "check_name" => "NO_CHECK",
            "amount" => bcmul((string)$amount, (string)100, 0),
            "desc" => "分销考核提现通过",
        ];

        $transfers = new Pay($jsapiOptions);
        return $transfers->createTransfers($data);
    }



    /**
     * 获取jsapiOptions
     * @return array
     */
    private function getJsapiOptions()
    {
        $data=[
            "appid" => $this->options['configuration']['AppId'],
            "mch_id" => $this->options['configuration']['MchId'],
            "mch_key" => $this->options['configuration']['APIKEY'],
            "ssl_key" => root_path(). "runtime/" . $this->options['wxkey'],
            "ssl_cer" => root_path(). "runtime/" . $this->options['cert']
        ];
        if ($this->options['type']==2){
            $data['appid']=$this->options['configuration']['M_AppId'] ?? '';
            $data['mch_id']=$this->options['configuration']['M_MchId'] ?? '';
            $data['ssl_key']=empty($this->options['M_wxkey'])? '' :root_path(). "runtime/" . $this->options['M_wxkey'] ;
            $data["ssl_cer"] = empty($this->options['M_cert']) ? '' :root_path(). "runtime/" . $this->options['M_cert'] ;
            $data['mch_key']=$this->options['configuration']['M_APIKEY'] ?? '';
        }

        return $data;
    }

    /**
     * 获取微信参数
     * @param $baseIn
     * @param $method
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function getOptions($baseIn, $method)
    {
        $configuration = Configuration::where(['type' => "mallPayMode"])->value("configuration");
        if (empty($configuration))
            throw new Exception("未完善支付配置");
        $configuration = json_decode($configuration, true);

        if (empty($configuration[$baseIn][$method]))
            throw new Exception("未开启支付配置");

        if (in_array($method, ['wx', 'ali'])) {
            $options = PayMode::find($configuration[$baseIn][$method . "_pay_mode_id"]);
            if (!$options)
                throw new Exception("为配置支付模板");
            $this->options = $options->toArray();
        }
    }

}